package com.supor.aiot.home.helper;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.text.TextUtils;

import com.android.baseconfig.common.utils.Logc;
import com.android.baseconfig.common.utils.StringUtils;
import com.android.baseconfig.common.utils.ThreadUtils;
import com.supor.aiot.common.app.Constants;
import com.supor.aiot.common.helper.WifiStationManager;

import java.util.ArrayList;
import java.util.List;

import static android.content.Context.WIFI_SERVICE;

/**
 * ---------------------------------------------------------------- <br>
 * Copyright (C) 2014-2020, by het, Shenzhen, All rights reserved.  <br>
 * ---------------------------------------------------------------- <br>
 * <p>
 * 描述: APHelper <br>
 * 作者: lei <br>
 * 日期: 2020/12/4 <br>
 */
public class APHelper {
    private static final String TAG = "APHelper";
    private Context context;
    IntentFilter intentFilter;
    ScanReceiver scanReceiver;
    private static boolean stopScan = false;
    private ScanListener scanListener;

    public enum Step {
        SUCCESS,
        NO_FOUND_AP,
        MULTI_AP,
        FAILURE,
        CONN_AP_FAILURE,
        CONN_ROUTER_FAILURE,
    }

    public APHelper(Context context, ScanListener scanListener) {
        this.context = context;
        this.scanListener = scanListener;
        intentFilter = new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
    }

    public void getScanResultList(String prefix) {
        registerScan();
        stopScan = false;
        ThreadUtils.execute(() -> {
            int retry = 0;
            boolean b = WifiStationManager.getInstance().startScan();
            Logc.i("startScan: " + b);
            while (!b && retry < 1) {
                retry++;
                Logc.d("getScanResultList: scan return false, wait 3s");
                sleep(3000);
                b = WifiStationManager.getInstance().startScan();
            }
            // sleep(2500);
            stopScan = true;
        });
    }

    public void connectAP(ScanResult scanResult, ConnectListener listener) {
        ThreadUtils.execute(() -> {
            // boolean b = WifiStationManager.getInstance().connectWifi(scanResult, null);
            // connectWifiApByNameAndPwd(SuporApplication.getInstance(),
            //         StringUtils.filterQuotedString(scanResult.SSID), "12345678",
            //         listener::onResult);
            connectWifiApByNameAndPwd(scanResult, listener::onResult);

        });
    }

    private void sleep(long time) {
        try {
            Thread.sleep(time);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public interface ScanListener {
        void scanResult(List<ScanResult> scanResults);
    }

    public interface ConnectListener {
        void onResult(boolean success);
    }

    public interface CallBack {
        void connectResult(boolean connectResult);
    }

    public void registerScan() {
        if (scanReceiver == null) {
            scanReceiver = new ScanReceiver(scanListener);
            context.registerReceiver(scanReceiver, intentFilter);
        }
    }

    public void unregisterScan() {
        context.unregisterReceiver(scanReceiver);
        scanReceiver = null;
    }

    public static class ScanReceiver extends BroadcastReceiver {
        private ScanListener scanListener;

        public ScanReceiver(ScanListener scanListener) {
            this.scanListener = scanListener;
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            Logc.i("receive scan action---------");
            List<ScanResult> scanResults =
                    WifiStationManager.getInstance().getScanResultList(false);
            if (scanResults == null) {
                if (scanListener != null && stopScan) {
                    scanListener.scanResult(null);
                }
                return;
            }
            List<ScanResult> tempList = new ArrayList<>();
            for (ScanResult scanResult : scanResults) {
                if (scanResult.SSID == null) {
                    continue;
                }
                if (StringUtils.filterQuotedString(scanResult.SSID)
                        .startsWith(Constants.SUPOR_AP_PREFIX)) {
                    tempList.add(scanResult);
                }
            }
            if (tempList.size() == 0) {
                Logc.e("no found AP");
                if (scanListener != null && stopScan) {
                    scanListener.scanResult(null);
                }
            } else {
                if (scanListener != null) {
                    scanListener.scanResult(tempList);
                }
            }
        }
    }

    /**
     * 创建 WifiConfiguration，这里创建的是wpa2加密方式的wifi
     *
     * @param ssid     wifi账号
     * @param password wifi密码
     * @return
     */
    public static WifiConfiguration createWifiInfo(String ssid, String password) {
        WifiConfiguration config = new WifiConfiguration();
        config.allowedAuthAlgorithms.clear();
        config.allowedGroupCiphers.clear();
        config.allowedKeyManagement.clear();
        config.allowedPairwiseCiphers.clear();
        config.allowedProtocols.clear();
        config.SSID = "\"" + ssid + "\"";
        if (TextUtils.isEmpty(password)) {
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
            Logc.i(TAG, "password is ''");
            return config;
        }
        config.preSharedKey = "\"" + password + "\"";
        config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
        config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
        config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
        config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
        config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
        config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
        config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
        config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
        config.status = WifiConfiguration.Status.ENABLED;
        return config;
    }

    /**
     * 通过热点用户名和密码连接热点
     *
     * @param scanResult
     * @param callBack
     */
    public static void connectWifiApByNameAndPwd(ScanResult scanResult, CallBack callBack) {
        if (callBack == null) {
            Logc.i(TAG, "context == null || callBack == null");
            return;
        }
        if (WifiStationManager.getInstance().connectWifi(scanResult, Constants.SUPOR_AP_PWD)) {
            Logc.i(TAG, "切换到指定wifi成功");
            callBack.connectResult(true);
        } else {
            Logc.i(TAG, "切换到指定wifi失败");
            callBack.connectResult(false);
        }
    }

    public static void connectWifiApByNameAndPwd(Context context, ScanResult scanResult, CallBack callBack) {
        connectWifiApByNameAndPwd(context, StringUtils.filterQuotedString(scanResult.SSID), Constants.SUPOR_AP_PWD, callBack);
    }

    public static void connectWifiApByNameAndPwd(Context context, String wifiApName,
                                                 String password, CallBack callBack) {
        if (context == null || callBack == null) {
            Logc.i(TAG, "context == null || callBack == null");
            return;
        }
        if (TextUtils.isEmpty(wifiApName)) {
            Logc.i(TAG, "TextUtils.isEmpty(wifiApName)");
            callBack.connectResult(false);
            return;
        }
        WifiManager mWifiManager = (WifiManager) context.getSystemService(WIFI_SERVICE);
        WifiConfiguration wifiNewConfiguration = createWifiInfo(wifiApName, password);
        //使用wpa2的wifi加密方式
        int newNetworkId = mWifiManager.addNetwork(wifiNewConfiguration);
        if (newNetworkId == -1) {
            Logc.i(TAG, "操作失败,需要您到手机wifi列表中取消对设备连接的保存");
            callBack.connectResult(false);
            return;
        }
        Logc.i(TAG, "newNetworkId is: " + newNetworkId);
        // 如果wifi权限没打开（1、先打开wifi，2，使用指定的wifi
        if (!mWifiManager.isWifiEnabled()) {
            mWifiManager.setWifiEnabled(true);
        }
        boolean enableNetwork = mWifiManager.enableNetwork(newNetworkId, true);
        if (!enableNetwork) {
            Logc.i(TAG, "切换到指定wifi失败");
            callBack.connectResult(false);
            return;
        }
        Logc.i(TAG, "切换到指定wifi成功");
        callBack.connectResult(true);
    }

    public void destroy() {
        if (context != null && scanReceiver != null) {
            unregisterScan();
        }
    }
}
